﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;
using OpenQuarters.WebQuarters.Utils;
using System.IO;

namespace OpenQuarters.WebQuarters.Core
{
    public class JavaScript
    {
        public static CMSPageVersion PageContext
        {
            get { return ContextItem.GetItem("JavaScript.PageContext", () => CMSPage.Current); }
            set { ContextItem.SetItem("JavaScript.PageContext", value); }
        }

        /// <summary>
        /// Common scripts
        /// </summary>
        public static ResourceDescriptorCollection CommonScripts
        {
            get
            {
                return ApplicationItem.GetItem(
                    "__CMS_" + JavaScriptType.CommonScript.ToString() + "s",
                    () => new ResourceDescriptorCollection()
                );
            }
        }

        /// <summary>
        /// Page scripts, indexed by Page Version ID
        /// </summary>
        public static LimitedDictionary<long, ResourceDescriptorCollection> PageScripts
        {
            get
            {
                return SessionItem.GetItem(
                    "__CMS_" + JavaScriptType.PageScript.ToString() + "s",
                    () => new LimitedDictionary<long, ResourceDescriptorCollection>(20)
                );
            }
        }

        /// <summary>
        /// Startup scripts, indexed by Page Version ID
        /// </summary>
        public static LimitedDictionary<long, ResourceDescriptorCollection> StartupScripts
        {
            get
            {
                return SessionItem.GetItem(
                    "__CMS_" + JavaScriptType.StartupScript.ToString() + "s",
                    () => new LimitedDictionary<long, ResourceDescriptorCollection>(20)
                );
            }
        }


        /// <summary>
        /// Startup scripts, indexed by Page Version ID
        /// </summary>
        public static LimitedDictionary<long, ResourceDescriptorCollection> ModuleStartupScripts
        {
            get
            {
                return SessionItem.GetItem(
                    "__CMS_" + JavaScriptType.ModuleStartupScript.ToString() + "s",
                    () => new LimitedDictionary<long, ResourceDescriptorCollection>(20)
                );
            }
        }

        /// <summary>
        /// Admin scripts, indexed by Page Version ID
        /// </summary>
        public static LimitedDictionary<long, ResourceDescriptorCollection> AdminScripts
        {
            get
            {
                return SessionItem.GetItem(
                    "__CMS_" + JavaScriptType.AdminScript.ToString() + "s",
                    () => new LimitedDictionary<long, ResourceDescriptorCollection>(20)
                );
            }
        }

        /// <summary>
        /// Admin startup scripts, indexed by Page Version ID
        /// </summary>
        public static LimitedDictionary<long, ResourceDescriptorCollection> AdminStartupScripts
        {
            get
            {
                return SessionItem.GetItem(
                    "__CMS_" + JavaScriptType.AdminStartupScript.ToString() + "s",
                    () => new LimitedDictionary<long, ResourceDescriptorCollection>(20)
                );
            }
        }

        public static void RegisterScript(string fileName, string source, JavaScriptType scriptType)
        {
            RegisterScript(new ResourceDescriptor(fileName, null, null, source), scriptType);
        }

        public static void RegisterScript(string fileName, string assembly, string filePath, JavaScriptType scriptType)
        {
            RegisterScript(new ResourceDescriptor(fileName, assembly, filePath, null), scriptType);
        }

        public static void RegisterScript(ResourceDescriptor resource, JavaScriptType scriptType)
        {
            LimitedDictionary<long, ResourceDescriptorCollection> scripts = null;

            switch (scriptType)
            {
                case JavaScriptType.AdminScript:
                    scripts = AdminScripts;
                    break;
                case JavaScriptType.AdminStartupScript:
                    scripts = AdminStartupScripts;
                    break;
                case JavaScriptType.PageScript:
                    scripts = PageScripts;
                    break;
                case JavaScriptType.StartupScript:
                    scripts = StartupScripts;
                    break;
                case JavaScriptType.ModuleStartupScript:
                    scripts = ModuleStartupScripts;
                    break;
                case JavaScriptType.CommonScript:
                    CommonScripts.Add(resource);
                    break;
            }

            if (scripts != null)
            {
                scripts[PageContext.PageVersionId].Add(resource);
            }
        }

        public static void ClearScripts()
        {
            AdminScripts[PageContext.PageVersionId].Clear();
            AdminStartupScripts[PageContext.PageVersionId].Clear();
            PageScripts[PageContext.PageVersionId].Clear();
            StartupScripts[PageContext.PageVersionId].Clear();
            ModuleStartupScripts[PageContext.PageVersionId].Clear();
        }

        public static void RegisterCommonScripts()
        {
            JavaScript.CommonScripts.Clear();
            foreach (var t in GeneralUtils.GetSubclassesOf(typeof(IJavaScriptProvider), true))
            {
                ((IJavaScriptProvider)Activator.CreateInstance(t)).RegisterJavaScripts();
            }
        }
    }

    public enum JavaScriptType
    {
        CommonScript,
        PageScript,
        StartupScript,
        ModuleStartupScript,
        AdminScript,
        AdminStartupScript
    }
}
